#include <iostream>
#include <vector>
#include <string>
using namespace std;

vector<int> bank; //银行
vector<vector<int>> hold;
vector<vector<int>> need;

class ThreadData
{
public:
    ThreadData() {}
    ThreadData(const string& name, const vector<int>& hold, const vector<int>& need)
        :_name(name)
        , _hold(hold)
        , _need(need)
    {}
public:
    string _name; //进程名
    vector<int> _hold; //目前持有的资源
    vector<int> _need; //目前持需要的资源
};

vector<ThreadData> tharr; //线程信息数组

bool safe()
{
    vector<int> order = bank;
    int num = hold.size();
    vector<int> v(num, 1); //位图
    int other = num;//旧的
    while (true)
    {
        for (int i = 0; i < hold.size(); ++i) //逐一
        {
            if (v[i] == 0) continue;
            vector<int> h = hold[i];
            vector<int> n = need[i];
            int flag = 1; //判断是否可以借款
            for (int k = 0; k < bank.size(); ++k)
            {
                //银行持有+目前持有>=需求
                if ((bank[k] + h[k]) < n[k])
                {
                    flag = 0;
                    break;
                }
            }
            if (flag)
            {
                for (int k = 0; k < bank.size(); ++k)
                {
                    bank[k] += h[k];
                    h[k] = 0;
                }
                v[i] = 0; //完成一个线程就标记位图
                --num;
                cout << "P" << i + 1 << "完成需求!" << endl;
            }
        }
        if (num == other)
            return false;

        if (!num) break;

        other = num;
    }
    bank = order;

    return true;

}

int main()
{
    int num = 0;
    cout << "请输入资源种类数:";
    cin >> num;
    bank.resize(num);
    cout << "请输入银行剩余的" << num << "个资源!(可以空格分割一次输入全部):";
    for (int i = 0; i < num; ++i)
    {
        cin >> bank[i];
    }
    int n = 0;
    cout << "请输入用户数(线程数):";
    cin >> n;
    hold.resize(n, vector<int>(num));
    need.resize(n, vector<int>(num));
    cout << "接下来输入" << n << "个用户已持有和需要的资源!" << endl;
    for (int i = 0; i < n; ++i)
    {
        cout << "请输入" << i + 1 << "个用户的持有(可空格分割一次输入):";
        for (int k = 0; k < num; ++k)
        {
            cin >> hold[i][k];
        }
        cout << "请输入" << i + 1 << "个用户的需求(可空格分割一次输入):";
        for (int k = 0; k < num; ++k)
        {
            cin >> need[i][k];
        }
    }
    //提前构造线程信息
    // tharr.resize(n);
    // for (int i = 0; i < n; ++i)
    // {
    //     char buf[64] = { 0 };
    //     snprintf(buf, sizeof(buf), "%c%d", 'p', i + 1);
    //     tharr[i]._name = buf;
    //     tharr[i]._hold = hold[i];
    //     tharr[i]._need = need[i];
    // }
    while (true)
    {
        int input = 0;
        cout << "1.求现在数据的安全情况" << endl;
        cout << "2.求更改需求后的安全情况" << endl;
        cout << "0.退出" << endl;
        cout << "请输入请求：";
        cin >> input;
        if (input == 0) break;
        if (input == 1)
        {
            if (safe())
                cout << "安全！" << endl;
            else
                cout << "不安全！" << endl;
        }
        if (input == 2)
        {
            int in1 = 0;
            int in2 = 0;

            cout << "1.更改持有" << endl;
            cout << "2.更改需求" << endl;
            cout << "请输入操作:";
            cin >> in1;
            cout << "请输入操作线程:";
            cin >> in2;
            if (in2 > n)
            {
                cout << "无此线程！" << endl;
                continue;
            }
            if (in1 == 1)
            {
                auto order = hold[in2]; //获取旧的持有备份
                cout << "请输入新需求:";
                for (int i = 0; i < hold[in2].size(); ++i)
                {
                    cin >> hold[in2][i];
                }
                if (safe())
                    cout << "安全！" << endl;
                else
                    cout << "不安全！" << endl;

                hold[in2] = order;
            }
            if (in1 == 2)
            {
                auto order = need[in2]; //获取旧的需求备份
                cout << "请输入新需求:";
                for (int i = 0; i < hold[in2].size(); ++i)
                {
                    cin >> need[in2][i];
                }
                if (safe())
                    cout << "安全！" << endl;
                else
                    cout << "不安全！" << endl;

                need[in2] = order;
            }
        }
    }
    return 0;
}